#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include "file_answer.h"
#include "configure.h"
#include "url_info.h"

extern struct conf *gconf;

#define UDP_BUFF_LEN 1500
#define TRAKER_UDP_PORT 81
#define LOCAL_UDP_PORT 81

int process_one_task(int sock, struct sockaddr_in *addr_peer, struct url_info *url_info, struct conf *conf)
{
	u_int exist;
	u_int rnum;
	int ret;

	if (conf->use_map)
	{
		if (create_full_path(url_info, conf) < 0)
			return -1;
		exist = file_exist(url_info->file_path);
	} else
	{
		rnum = rand()%100;
		if (create_relative_path(url_info) < 0)
		{
			return -1;
		}
		exist = relative_path_exist(url_info, rnum, conf);
	}

	if (exist)
	{
		addr_peer->sin_port = htons(TRAKER_UDP_PORT);
		ret = sendto(sock, url_info->url, strlen(url_info->url), 0, 
				(struct sockaddr*)addr_peer, sizeof(struct sockaddr_in));
	}

	return ret;
}

void* answer_proc(void *parm)
{
	int sock;
	int nrecv;
	struct sockaddr_in addr_lsn, addr_peer;
	socklen_t addr_peer_len;

	srand(time(0));

	memset(&addr_lsn, 0, sizeof(addr_lsn));
	addr_lsn.sin_family = AF_INET;
	addr_lsn.sin_port = htons(LOCAL_UDP_PORT);
	addr_lsn.sin_addr.s_addr = htonl(INADDR_ANY);

	if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
	{
		printf("socket() error\n");
		_exit(0);
	}

	if (bind(sock, (struct sockaddr*)&addr_lsn, (socklen_t)sizeof(addr_lsn)) < 0)
	{
		printf("udp bind() fail\n");
		_exit(0);
	}

	while(1)
	{
		struct url_info url_info;
		addr_peer_len = sizeof(addr_peer);
		nrecv = recvfrom(sock, url_info.buff, sizeof(url_info.buff) - 1, 0, (struct sockaddr*)&addr_peer, &addr_peer_len);
		if (nrecv <= 0)
		{
			sleep(1);
			continue;
		}
		url_info.buff[nrecv] = 0;
		url_info.url = url_info.buff;
		if (locate_filename_and_qmark(&url_info) < 0)
			continue;

		process_one_task(sock, &addr_peer, &url_info, gconf);
	}

	return 0;

}


void start_file_answer()
{	
	pthread_t t;
	if (pthread_create(&t, 0, answer_proc, 0) != 0)
	{
		perror("pthread_create");
		_exit(0);
	}

}


